﻿namespace NJQuery {
	using System;
	using System.Web.UI;
	using System.ComponentModel;

	/// <summary>
	/// Server control used to generate a <see href="http://jqueryui.com/demos/progressbar/">jQuery UI Progressbar widget</see>.
	/// </summary>
	public class ProgressBar : ManagedWebControl {


		#region Constants: Property value defaults

		private const int defaultValue = 0;

		#endregion


		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="ProgressBar"/> class.
		/// </summary>
		public ProgressBar() : base(HtmlTextWriterTag.Div) { }

		#endregion


		#region Properties: Widget initialization options

		/// <summary>
		/// The value of the progressbar on a 0 to 100 percentage scale.
		/// This property maps directly to the "value" option when the jQuery UI widget is initialized.
		/// </summary>
		[DefaultValue(defaultValue), Category("Appearance")]
		public virtual int Value {
			get { return ViewState["Value"] as int? ?? defaultValue; }
			set { ViewState["Value"] = value; }
		}

		#endregion


		#region Methods: Rendering hooks

		/// <summary>
		/// Allows a jQuery server control to reference scripts and stylesheets necessary to render their client markup and widgets.
		/// </summary>
		/// <param name="manager">The <see cref="Manager"/> used to handle style and script referencing in addition to unified generation of load and ready scripts.</param>
		protected override void Register(Manager manager) {

			manager.RegisterClientScript(ClientScript.Core);
			manager.RegisterClientScript(ClientScript.UIWidgetFactory);
			manager.RegisterClientScript(ClientScript.UIProgressBarWidget);

			manager.RegisterClientStyle(ClientStyle.UICore);
			manager.RegisterClientStyle(ClientStyle.UIProgressBarWidget);
			manager.RegisterTheme();

			manager.RegisterForReadyScript(this);
		}

		/// <summary>
		/// Renders the jQuery "Ready Event" script required to generate the client-side jQuery widget.
		/// This method is used primarily by control developers.
		/// </summary>
		/// <param name="script">A <see cref="ScriptBuilder"/> that creates the output stream to render jQuery JavaScript on the client.</param>
		protected override void RenderReadyScript(ScriptBuilder script) {
			RenderInitScript(script);
		}

		/// <summary>
		/// Renders the jQuery UI initialization script.
		/// This method is used primarily by control developers.
		/// </summary>
		/// <param name="script">A <see cref="ScriptBuilder"/> that creates the output stream to render jQuery JavaScript on the client.</param>
		protected virtual void RenderInitScript(ScriptBuilder script) {

			script.RenderIdSelector(ClientID);
			script.Append(".progressbar(");

			PropertyCollection properties = script.CreateProperties();
			AddInitProperties(properties);
			script.RenderProperties(properties);

			script.Append(");");
		}

		/// <summary>
		/// Creates the properties object that will be rendered as the jQuery UI initialization options.
		/// This method is used primarily by control developers.
		/// </summary>
		/// <param name="properties">A <see cref="PropertyCollection"/> object that will become the jQuery UI initialization options.</param>
		protected virtual void AddInitProperties(PropertyCollection properties) {

			int value = Value;
			properties.AddValue("value", value);

		}

		#endregion


		#region Methods: Script helpers

		/// <summary>
		/// Creates jQuery script to update a value on the client.
		/// </summary>
		/// <returns>Returns jQuery script to update the value on the client.</returns>
		public string GenerateValueUpdateScript() {
			ScriptBuilder script = new ScriptBuilder();
			script.RenderIdSelector(ClientID);
			script.Append(".progressbar(");
			script.AppendValue("value");
			script.Append(",");
			script.AppendValue(Value);
			script.Append(");");
			return script.ToString();
		}

		/// <summary>
		/// Registers a jQuery script to update the value on the client with the <see cref="ScriptManager"/> 
		/// </summary>
		/// <param name="updateControl">A <see cref="Control"/> with proper scope and location to be updated via an <see cref="UpdatePanel"/> style call.</param>
		public void RegisterValueUpdateScript(Control updateControl) {
			ScriptManager.RegisterStartupScript(updateControl, typeof(ProgressBar), "ValueUpdate", GenerateValueUpdateScript(), true);
		}

		#endregion


	}

}